#include "stdafx.h"
#include "srs_rtu_stack.hpp"
//#include <srs_kernel_log.hpp>
//#include <srs_kernel_error.hpp>
//#include <srs_kernel_utility.hpp>

#include <math.h>
#include <algorithm>

int SrsRtuPacket::encode(int& psize, char*& ppayload)
{
    int ret = ERROR_SUCCESS;
    int size = get_size();
    char* payload = 0;

    SrsStream stream;

    if (size > 0) {
        payload = new char[size];

        if ((ret = stream.initialize(payload, size)) != ERROR_SUCCESS) {
//            rtu_error("initialize the stream failed. ret=%d", ret);
            srs_freepa(payload);
            return ret;
        }
    }

    if ((ret = encode_packet(&stream)) != ERROR_SUCCESS) {
//        rtu_error("encode the packet failed. ret=%d", ret);
        srs_freepa(payload);
        return ret;
    }

    psize = size;
    ppayload = payload;
//    rtu_verbose("encode the packet success. size=%d", size);

    return ret;
}

int SrsRtuPacket::decode(SrsStream* stream)
{
    int ret = ERROR_SUCCESS;

    srs_assert(stream != NULL);

    ret = ERROR_SYSTEM_PACKET_INVALID;
//    rtu_error("current packet is not support to decode. ret=%d", ret);

    return ret;
}

int SrsRtuPacket::get_size()
{
    return 0;
}

int SrsRtuPacket::encode_packet(SrsStream* stream)
{
    int ret = ERROR_SUCCESS;

    srs_assert(stream != 0);

    ret = ERROR_SYSTEM_PACKET_INVALID;
//    rtu_error("current packet is not support to encode. ret=%d", ret);

    return ret;
}

SrsRtuStreamStartPacket::SrsRtuStreamStartPacket()
{
    command = SrsRtuCmdStreamStart;
    // 6(base header) + 200 + 4 + 4 + 4 = 218
    length = 218;
    memset(url,0,200);
}

SrsRtuStreamStartPacket::~SrsRtuStreamStartPacket()
{

}

int SrsRtuStreamStartPacket::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if(  !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( length != (DWORD)stream->read_4bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    stream->read_bytes(url,200);
    ip = stream->read_4bytes();
    data_port = stream->read_4bytes();
    retransmission_port = stream->read_4bytes();

//    rtu_verbose("decode rtu packet success.");
    return ret;
}

int SrsRtuStreamStartPacket::get_size()
{
    // 6(base header) + 200 + 4 + 4 + 4 = 218
    return 218;
}

int SrsRtuStreamStartPacket::encode_packet(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if (!stream->require(get_size())) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
//        rtu_error("encode rtu packet failed. ret=%d", ret);
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);

    stream->write_bytes(url,200);
    stream->write_4bytes(ip);
    stream->write_4bytes(data_port);
    stream->write_4bytes(retransmission_port);

//    rtu_verbose("encode rtu packet success. size=%d", length);

    return ret;
}


SrsRtuStreamStartResponsePacket::SrsRtuStreamStartResponsePacket()
{
    command = SrsRtuCmdStreamStartResponse;
    length = 6 + 2 + 200 + 4 + 4;
    error_code = SrsRtuErrorSuccess;
    memset(url,0,200);
    stream_id = 0xffffffff;
    byterate = 0xffffffff;
}

SrsRtuStreamStartResponsePacket::~SrsRtuStreamStartResponsePacket()
{

}

int SrsRtuStreamStartResponsePacket::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if(  !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    if( length != (DWORD)stream->read_4bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    error_code = stream->read_2bytes();
    stream->read_bytes(url,200);
    stream_id = (DWORD)stream->read_4bytes();
    byterate = (DWORD)stream->read_4bytes();

    return ret;
}

int SrsRtuStreamStartResponsePacket::get_size()
{
    return length;
}

int SrsRtuStreamStartResponsePacket::encode_packet(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if (!stream->require(get_size())) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
//        rtu_error("encode rtu packet failed. ret=%d", ret);
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);

    stream->write_2bytes(error_code);
    stream->write_bytes(url,200);
    stream->write_4bytes(stream_id);
    stream->write_4bytes(byterate);

//    rtu_verbose("encode rtu packet success. size=%d", length);

    return ret;
}

SrsRtuStreamDataPacket::SrsRtuStreamDataPacket(uint16_t cmd)
{
    // can be SrsRtuCmdStreamData or SrsRtuCmdRetransmissionResponse
    command = cmd;
    // 6(basehead) + 4 + 1 + 4 * 5
    length  = 39;
    payload_size = 0;
    video_packet_no = 0;
    audio_packet_no = 0;

    _delay = 0;
}

SrsRtuStreamDataPacket::~SrsRtuStreamDataPacket()
{
}

int SrsRtuStreamDataPacket::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if(  !stream->require(6) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    command = stream->read_2bytes();
    if( command != SrsRtuCmdStreamData && command != SrsRtuCmdRetransmissionResponse) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    length = stream->read_4bytes();
    if(  length < 39 || length > SRS_RTU_PACKET_SIZE_LIMIT || !stream->require(length - 6) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }
    payload_size = length -39;

    stream_id = stream->read_4bytes();
    stream_type = stream->read_1bytes();
    timestamp = stream->read_4bytes();
    packet_no = stream->read_4bytes();
    video_packet_no = stream->read_4bytes();
    audio_packet_no = stream->read_4bytes();
    message_no = stream->read_4bytes();
    slice_sum = stream->read_4bytes();
    slice_no = stream->read_4bytes();
    stream->read_bytes(payload(),payload_size);

    return ret;
}

int SrsRtuStreamDataPacket::get_size()
{
    // basehead and payload
    length = 39 + payload_size;
    return length;
}

int SrsRtuStreamDataPacket::encode_packet(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if(payload_size > (SRS_RTU_PACKET_DATA_SIZE_LIMIT) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
        return ret;
    }

    if (!stream->require(get_size())) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);

    stream->write_4bytes(stream_id);
    stream->write_1bytes(stream_type);
    stream->write_4bytes(timestamp);
    stream->write_4bytes(packet_no);
    stream->write_4bytes(video_packet_no);
    stream->write_4bytes(audio_packet_no);
    stream->write_4bytes(message_no);
    stream->write_4bytes(slice_sum);
    stream->write_4bytes(slice_no);
    stream->write_bytes(payload(), payload_size);

    return ret;
}

int SrsRtuStreamDataPacket::set_payload(char *p, int size)
{
    srs_assert(p);
    srs_assert(size);

    int ret = ERROR_SUCCESS;

    if(size > (SRS_RTU_PACKET_SIZE_LIMIT - 31) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
        return ret;
    }

    memcpy(buff + 39,p,size);
    payload_size = size;

    return ret;
}

char* SrsRtuStreamDataPacket::payload()
{
    return buff + 39;
}

int SrsRtuStreamDataPacket::encode_inside()
{
    int ret = ERROR_SUCCESS;

    SrsStream stream;
    stream.initialize(buff, 39);

    stream.write_2bytes(command);
    stream.write_4bytes(get_size());

    stream.write_4bytes(stream_id);
    stream.write_1bytes(stream_type);
    stream.write_4bytes(timestamp);
    stream.write_4bytes(packet_no);
    stream.write_4bytes(video_packet_no);
    stream.write_4bytes(audio_packet_no);
    stream.write_4bytes(message_no);
    stream.write_4bytes(slice_sum);
    stream.write_4bytes(slice_no);

    return ret;
}

SrsRtuStreamDataPacket *SrsRtuStreamDataPacket::copy()
{
    SrsRtuStreamDataPacket* copy = new SrsRtuStreamDataPacket();

    copy->command = command;
    copy->length  = get_size();
    copy->stream_id = stream_id;
    copy->stream_type = stream_type;
    copy->timestamp = timestamp;
    copy->packet_no = packet_no;
    copy->video_packet_no = video_packet_no;
    copy->audio_packet_no = audio_packet_no;
    copy->message_no = message_no;
    copy->slice_sum = slice_sum;
    copy->slice_no = slice_no;
    copy->payload_size = payload_size;
    memcpy(copy->buff, buff, SRS_RTU_PACKET_SIZE_LIMIT);

    return copy;
}

SrsRtuStreamDataPacket &SrsRtuStreamDataPacket::operator=(SrsRtuStreamDataPacket &pkt)
{
    if(this == &pkt) {
        return *this;
    }

    command = pkt.command;
    length = pkt.get_size();
    stream_id = pkt.stream_id;
    stream_type = pkt.stream_type;
    timestamp = pkt.timestamp;
    packet_no = pkt.packet_no;
    video_packet_no = pkt.video_packet_no;
    audio_packet_no = pkt.audio_packet_no;
    message_no = pkt.message_no;
    slice_sum = pkt.slice_sum;
    slice_no = pkt.slice_no;
    payload_size = pkt.payload_size;
    memcpy(buff, pkt.buff, SRS_RTU_PACKET_SIZE_LIMIT);

    return *this;
}

SrsRtuRtnsRequestPacket::SrsRtuRtnsRequestPacket()
{
    command = SrsRtuCmdRetransmissionRequest;
    // 6 + 4 + 1 + 4 + 4 * packet_sum( default 0 ) = 15
    length = 16;
    stream_id = 0xFFFFFFFF;
	stream_type = 0;
    packet_sum = 0;
}

SrsRtuRtnsRequestPacket::~SrsRtuRtnsRequestPacket()
{
    packet_no_list.clear();
}

int SrsRtuRtnsRequestPacket::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if( !stream->require(16) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    length      = stream->read_4bytes();
    stream_id   = stream->read_4bytes();
	stream_type = stream->read_1bytes();


    level = level > 3 ? 3 : level;
    level       = stream->read_1bytes();
    packet_sum  = stream->read_4bytes();

    // packet_no_list size is 4 * packet_sum
    if(  !stream->require( 4 * packet_sum) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    for(DWORD i = 0; i < packet_sum; i++) {
        DWORD rtns_req_pkt_no = stream->read_4bytes();
        packet_no_list.push_back(rtns_req_pkt_no);
    }

//    rtu_verbose("decode rtu packet success.");

    return ret;
}

int SrsRtuRtnsRequestPacket::get_size()
{
    return 16 + 4 * packet_no_list.size();
}

int SrsRtuRtnsRequestPacket::encode_packet(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;
    packet_sum = packet_no_list.size();

    if (!stream->require(get_size())) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
//        rtu_error("encode rtu packet failed. ret=%d", ret);
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);
	stream->write_1bytes(stream_type);

    stream->write_4bytes(stream_id);

    level = level > 3 ? 3 : level;
    stream->write_1bytes(level);
    stream->write_4bytes(packet_sum);

    for(int i = 0; i < packet_no_list.size(); i++) {
        stream->write_4bytes(packet_no_list[i]);
    }

//    rtu_verbose("encode rtu packet success. size=%d", length);

    return ret;
}

SrsRtuRtnsResponseEncodePacket::SrsRtuRtnsResponseEncodePacket()
{
    command = SrsRtuCmdRetransmissionResponse;
    length = 0;
    level = 0;
}

SrsRtuRtnsResponseEncodePacket::~SrsRtuRtnsResponseEncodePacket()
{
    clear();
}

int SrsRtuRtnsResponseEncodePacket::get_size()
{
    length = 0;
    for(int i = 0; i < pkts.size(); i++) {
        SrsRtuStreamDataPacket* packet  = pkts[i];
        length += packet->get_size();
    }

    return length;
}

int SrsRtuRtnsResponseEncodePacket::encode_packet(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if( !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
//        rtu_error("encode rtu packet failed.");
        return ret;
    }

    for( int i = 0; i < pkts.size(); i++ ) {
        SrsRtuStreamDataPacket* packet = pkts[i];
        if((ret = packet->encode_packet(stream)) != ERROR_SUCCESS) {
//            rtu_error("encode rtu packet failed.");
            return ret;
        }
    }

//    rtu_verbose("encode rtu packet success.");
    return ret;
}

int SrsRtuRtnsResponseEncodePacket::encode_inside()
{
    SrsStream buffer;
    buffer.initialize(buff,SRS_RTU_PACKET_SIZE_LIMIT);
    return encode_packet(&buffer);
}

void SrsRtuRtnsResponseEncodePacket::enqueue(SrsRtuStreamDataPacket* packet)
{
    srs_assert(packet);
    srs_assert(packet->command == SrsRtuCmdStreamData||
               packet->command == SrsRtuCmdRetransmissionResponse);

    packet->command = SrsRtuCmdRetransmissionResponse;

    pkts.push_back(packet);
}

void SrsRtuRtnsResponseEncodePacket::clear()
{
    for(int i = 0; i < pkts.size(); i++ ) {
        SrsRtuStreamDataPacket* packet = pkts[i];
        srs_freep(packet);
    }
    pkts.clear();
}

void SrsRtuRtnsResponseEncodePacket::set_level(uint8_t rtns_level)
{
    level = rtns_level > 3 ? 3 : rtns_level;
}

uint8_t SrsRtuRtnsResponseEncodePacket::get_level()
{
    return level;
}

SrsRtuRtnsResponseDecodePacket::SrsRtuRtnsResponseDecodePacket()
{
    command = SrsRtuCmdRetransmissionResponse;
    length = 0;
}

SrsRtuRtnsResponseDecodePacket::~SrsRtuRtnsResponseDecodePacket()
{
    clear();
}

int SrsRtuRtnsResponseDecodePacket::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;
    SrsRtuStreamDataPacket* data_packet = 0;

    while( !stream->empty() ) {
        data_packet = new SrsRtuStreamDataPacket(SrsRtuCmdRetransmissionResponse);

        if( (ret = data_packet->decode(stream)) != ERROR_SUCCESS ) {
//            rtu_error("decode rtu packet failed.");
            return ret;
        }

        pkts.push_back(data_packet);
    }

//    rtu_verbose("decode rtu packet success.");
    return ret;
}

int SrsRtuRtnsResponseDecodePacket::get_size()
{
    length = 0;

    for(int i = 0; i < pkts.size(); i++) {
        length += pkts[i]->get_size();
    }

    return length;
}

void SrsRtuRtnsResponseDecodePacket::clear()
{
    std::vector<SrsRtuStreamDataPacket*>::iterator it = pkts.begin();

    for(; it != pkts.end(); ++it) {
        SrsRtuStreamDataPacket* pkt = *it;
        srs_freep(pkt);
    }

    pkts.clear();
}

SrsRtuStreamStopPacket::SrsRtuStreamStopPacket()
{
    command = SrsRtuCmdStreamStop;
    // 6 + 4
    length = 10;
}

SrsRtuStreamStopPacket::~SrsRtuStreamStopPacket()
{

}

int SrsRtuStreamStopPacket::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if(  !stream->require(10) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( length != (DWORD)stream->read_4bytes() ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    stream_id = stream->read_4bytes();

//    rtu_verbose("decode rtu packet success.");

    return ret;
}

int SrsRtuStreamStopPacket::get_size()
{
    return 10;
}

int SrsRtuStreamStopPacket::encode_packet(SrsStream *stream)
{
    int ret =  ERROR_SUCCESS;

    if ( !stream->require(10) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
//        rtu_error("encode rtu packet failed.");
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);

    stream->write_4bytes(stream_id);

//    rtu_verbose("encode rtu packet success. size=%d", length);

    return ret;
}


SrsRtuHeartbeat::SrsRtuHeartbeat()
{
    command = SrsRtuCmdHeartbeat;
    // 6 + 4 + 4
    length = 14;

    stream_id = 0xffffffff;
    data = 0xffffffff;
}

SrsRtuHeartbeat::SrsRtuHeartbeat(DWORD id)
{
    command = SrsRtuCmdHeartbeat;
    // 6 + 4 + 4
    length = 14;

    stream_id = id;
    data = 0xffffffff;
}

SrsRtuHeartbeat::~SrsRtuHeartbeat()
{

}

int SrsRtuHeartbeat::decode(SrsStream *stream)
{
    int ret = ERROR_SUCCESS;

    if(  !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    if( length != (DWORD)stream->read_4bytes() ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
//        rtu_error("decode rtu packet failed.");
        return ret;
    }

    stream_id = stream->read_4bytes();
    data = stream->read_4bytes();
//
//    rtu_verbose("decode rtu packet success.");

    return ret;
}

int SrsRtuHeartbeat::get_size()
{
    return length;
}

int SrsRtuHeartbeat::encode_packet(SrsStream *stream)
{
    int ret =  ERROR_SUCCESS;

    if ( !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
//        rtu_error("encode rtu packet failed.");
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);

    stream->write_4bytes(stream_id);
    stream->write_4bytes(data);

//    rtu_verbose("encode rtu packet success. size=%d", length);

    return ret;
}

int SrsRtuHeartbeat::encode_inside()
{
    SrsStream buffer;
    buffer.initialize(buff, 14);

    return encode_packet(&buffer);
}



SrsRtuStreamPush::SrsRtuStreamPush(){
	command = SrsRtuCmdStreamPush;
	//6(base header) + 200
	length = 206;
	memset(url,0,200);
}

SrsRtuStreamPush::~SrsRtuStreamPush(){

}

int SrsRtuStreamPush::decode(SrsStream* stream){
    int ret = ERROR_SUCCESS;

    if( !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    if( length != (DWORD)stream->read_4bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    stream->read_bytes(url,200);

    return ret;
}

int SrsRtuStreamPush::get_size(){
	return  length;
}

int SrsRtuStreamPush::encode_packet(SrsStream* stream){
    int ret =  ERROR_SUCCESS;

    if ( !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);
    stream->write_bytes(url,200);

    return ret;
}
//stop push
SrsRtuStreamStopPush::SrsRtuStreamStopPush(){
	command = SrsRtuCmdStreamPushStop;
	//6(base header) + 200
	length = 206;
	memset(url,0,200);
}

SrsRtuStreamStopPush::~SrsRtuStreamStopPush(){

}

int SrsRtuStreamStopPush::decode(SrsStream* stream){
    int ret = ERROR_SUCCESS;

    if( !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    if( command != (uint16_t)stream->read_2bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    if( length != (DWORD)stream->read_4bytes()) {
        ret = ERROR_RTU_MESSAGE_DECODE;
        return ret;
    }

    stream->read_bytes(url,200);

    return ret;
}

int SrsRtuStreamStopPush::get_size(){
	return  length;
}

int SrsRtuStreamStopPush::encode_packet(SrsStream* stream){
    int ret =  ERROR_SUCCESS;

    if ( !stream->require(get_size()) ) {
        ret = ERROR_RTU_MESSAGE_ENCODE;
        return ret;
    }

    stream->write_2bytes(command);
    stream->write_4bytes(length);
    stream->write_bytes(url,200);

    return ret;
}
//stop push end

void rtu_usleep(int usec)
{
    struct timeval delay;
    delay.tv_sec = 0;
    delay.tv_usec = usec;
    select(0,0,0,0, &delay);
}

int rtu_sendto(int sockfd, const void *buf, int len, int flags, const sockaddr *dest_addr, int addrlen)
{
    //int nb_send = sendto(sockfd, buf, len, flags, dest_addr, addrlen);
    //if (nb_send <= 0) {
    //    if(nb_send < 0 ) {
//            rtu_error("rtu sendto error: %s.",strerror(errno));
    //    }
    //    return ERROR_SOCKET_SENDTO;
    //}

    return ERROR_SUCCESS;
}

INT64 rtu_get_system_time_us()
{
    //timeval now;
	SYSTEMTIME now;
	GetLocalTime(&now);
    //if (gettimeofday(&now, 0) < 0) {
//        rtu_warn("gettimeofday failed, ignore");
    //    return -1;
    //}
	INT64 now_us = ((INT64)now.wSecond) * 1000 * 1000 + (INT64)now.wMilliseconds;
    //INT64 now_us = ((INT64)now.tv_sec) * 1000 * 1000 + (INT64)now.tv_usec;


    return now_us;
}
